package ui;

import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import model.BlogPost;
import model.Topic;
import utils.MultipleFileSelector;

public class DataUploader extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	JTextArea topicNum;
	JButton openButton = new JButton("Open");
	JButton uploadButton = new JButton("Upload");
	JTextArea display;
	Vector<Topic> topics = new Vector<Topic>();
	JFileChooser fc = new JFileChooser();
	LabelingUI labelingUI = new LabelingUI();
	Connection conn = null;

	public void init() {
		startUI();
		setSize(500, 600);
		setVisible(true);
		startDBConnection();
	}

	private void startDBConnection() {
		String connectionURL = "jdbc:mysql://goanna.cs.rmit.edu.au:56555/research";

		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			display.append("Attempting to connect to the database ... \n");
			conn = DriverManager.getConnection(connectionURL, "root",
					"xsqj0123");
			display.append("Database connection established.\n");
		} catch (InstantiationException e) {
			display.append(e.getMessage());
		} catch (IllegalAccessException e) {
			display.append(e.getMessage());
		} catch (ClassNotFoundException e) {
			display.append(e.getMessage());
		} catch (SQLException e) {
			display.append(e.getMessage());
		}
	}

	public void startUI() {
		topicNum = new JTextArea(1, 3);
		display = new JTextArea(5, 80);
		display.setMargin(new Insets(5, 5, 5, 5));
		display.setEditable(false);
		display.setLineWrap(true);
		JScrollPane logScrollPane = new JScrollPane(display);
		logScrollPane
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		logScrollPane
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		JPanel buttonPanel = new JPanel(); // use FlowLayout
		buttonPanel.add(topicNum);
		buttonPanel.add(openButton);
		buttonPanel.add(uploadButton);

		// mainContainer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new BorderLayout());
		add(buttonPanel, BorderLayout.PAGE_START);
		add(logScrollPane, BorderLayout.CENTER);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);

		// mainContainer.pack();
		addListeners();
	}

	private void addListeners() {
		openButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String directory = "";
				if (!labelingUI.isBoundToDataSource()) {
					fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int returnVal = fc.showOpenDialog(null);
					if (returnVal == JFileChooser.APPROVE_OPTION) {
						display.append("Directory selected : "
								+ fc.getSelectedFile() + "\n");
						MultipleFileSelector selector = new MultipleFileSelector(
								fc.getSelectedFile().toString());
						display.append("Files selected : "
								+ selector.getSelectedToString());
						directory = fc.getSelectedFile().toString();
						labelingUI.bindDataSourceByPath(directory);
					} else {
						display.append("Open command cancelled by user.\n");
					}
				} else {
					int choice;
					do {
						choice = JOptionPane
								.showConfirmDialog(null,
										"Are you sure you wish to upload a different set of documents?");
						int returnVal;
						if (choice == JOptionPane.OK_OPTION) {
							// Reset everything to start labeling a new set of
							// docs
							labelingUI.resetDataSource();
							fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
							returnVal = fc.showOpenDialog(null);
							if (returnVal == JFileChooser.APPROVE_OPTION) {
								display.append("New directory selected : "
										+ fc.getSelectedFile() + "\n");
								MultipleFileSelector selector = new MultipleFileSelector(
										fc.getSelectedFile().toString());
								display.append("Files selected : "
										+ selector.getSelectedToString());
								directory = fc.getSelectedFile().toString();
								labelingUI.bindDataSourceByPath(directory);
							} else {
								display.append("Open command cancelled by user.\n");
							}
						} else if (choice == JOptionPane.CANCEL_OPTION) {
							display.append("Open command cancelled by user.\n");
						} else {
							// returnVal = fc.showOpenDialog(mainFrame);
							// if (returnVal == JFileChooser.APPROVE_OPTION) {
							// display.append("Directory to save to : "
							// + fc.getSelectedFile() + "\n");
							// }
						}
					} while (choice == JOptionPane.NO_OPTION);
				}
			}
		});

		uploadButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Upload commencing.");
				uploadToDB(topicNum.getText());
				System.out.println("Upload finished.");
			}
		});
	}

	/**
	 * Upload original documents to the database
	 */
	public void uploadToDB(String topic) {
		System.out.println(labelingUI.getRepo().size()
				+ " posts to be processed.");
		for (BlogPost post : labelingUI.getRepo()) {
			System.out.println("Uploading " + post.getID());
			display.append(post.upload(conn, topic));
		}
	}

	// Read topics from a local file
	public void readTopics(String topicFile) {
		FileInputStream fstream;
		String num = "", title = "", desc = "", narrative = "";
		File file = new File(topicFile);
		Topic thisTopic;
		try {
			fstream = new FileInputStream(file);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					fstream));
			String line = in.readLine();
			while (line != null) {
				// If the line starts with <top>
				if (line.contains("</top>")) {
					thisTopic = new Topic(num, title, title, desc, narrative);
					topics.add(thisTopic);
					num = title = desc = narrative = "";
					System.out.println(thisTopic.getTopicNo());
				} else if (line.contains("<num>")) {
					line = line.substring(5 + 8);
					// line = line.substring(0, line.indexOf("</"));
					num = num.concat(line.trim());
				} else if (line.contains("<title>")) {
					line = line.substring(8);
					// line = line.substring(0, line.indexOf("</"));
					title = title.concat(line);
				} else if (line.contains("<desc>")) {
					line = in.readLine();
					while (!line.trim().equals("")) {
						desc = desc.concat(line);
						line = in.readLine();
					}
				} else if (line.contains("<narr>")) {
					line = in.readLine();
					while (!line.trim().equals("")) {
						narrative = narrative.concat(line);
						line = in.readLine();
					}
				}
				line = in.readLine();
			}
			fstream.close();
		} catch (FileNotFoundException e) {
			System.out.println("Trying to read from " + file.toString());
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void uploadTopics() {

		PreparedStatement statement = null;

		try {
			statement = conn
					.prepareStatement("insert into topic (topic_no, title, query, description, narrative) values (?,?,?,?,?)");
			// Upload the sentences
			for (Topic t : topics) {
				statement.setString(1, t.getTopicNo());
				statement.setString(2, t.getTopicTitle());
				statement.setString(3, t.getTopicQuery());
				statement.setString(4, t.getTopicDescription());
				statement.setString(5, t.getTopicNarrative());
				System.out.println(statement.executeUpdate()
						+ " records affected.");
				System.out.println(t.toString());
				System.out.println("Topic " + t.getTopicNo() + " uploaded\n");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void uploadExamples(String examplesFile) {

		PreparedStatement statement = null;

		try {
			statement = conn.prepareStatement("insert into examples (topic_no,"
					+ " topicality_example1, topicality_example2, "
					+ "topicality_example3, topicality_example4,"
					+ "sentiment_example1, sentiment_example2,"
					+ "sentiment_example3, sentiment_example4) "
					+ "values (?,?,?,?,?,?,?,?,?)");

			// Upload the examples
			FileInputStream fstream = new FileInputStream(examplesFile);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					fstream));
			String line = in.readLine();
			while (line != null) {
				StringTokenizer stk = new StringTokenizer(line, "$");
				while (stk.hasMoreTokens()) {
					statement.setString(1, stk.nextToken());
					statement.setString(2, stk.nextToken());
					statement.setString(3, stk.nextToken());
					statement.setString(4, stk.nextToken());
					statement.setString(5, stk.nextToken());
					statement.setString(6, stk.nextToken());
					statement.setString(7, stk.nextToken());
					statement.setString(8, stk.nextToken());
					statement.setString(9, stk.nextToken());
					System.out.println(statement.executeUpdate()
							+ " records affected.");
				}
				line = in.readLine();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		DataUploader uploader = new DataUploader();
		uploader.init();
		// uploader.readTopics("06.topics.34");
		// uploader.uploadTopics();
		// uploader.uploadExamples("examples.txt");
	}
}
